﻿// 0925train02.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <limits>
#include <iomanip>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

/*
给定一段"密文"字符串s，其中字符都是经过"密码本"映射的，现需要将"密文"解密并且输出。
映射的规则 ："a-i"分别用"1-9"表示，"j-z" 分别用"10*-26*"表示

输入描述
“密文”字符串

输出描述
明文字符串

输入
20*19*20*
输出
tst
 */
class Solution01
{
public:
    Solution01(string&origin_str)
    {
        vector<int>num_vec;

        for (auto&ch:origin_str)
        {
            if (isdigit(ch))
            {
                num_vec.push_back(ch - '0');
            }
            if (ch=='*')
            {
                int back = num_vec.back();
                num_vec.pop_back();
                string str = to_string(back);
                back = num_vec.back();
                num_vec.pop_back();
                str = to_string(back) + str;
                num_vec.push_back(stoi(str));
            }
        }

        string result;
        for (auto&num:num_vec)
        {
            char curr_ch = 'a' + (num - 1);
            result += curr_ch;
        }
        cout << result;
	    //Solution01
    }
};


/*
 一个人设定一组四码的数字作为谜底，另一方猜。
每猜一个数，出数者就要根据这个数字给出提示，提示以XAYB形式呈现，直到猜中为止。
其中X表示位置正确的数的个数(数字正确且位置正确)，而Y表示数字正确而位置不对的数的个数。
例如，当谜底为8123，而猜谜者猜1052时，出题者必须提示0A2B.
例如，当谜底为5637，而猜谜者猜4931时，出题者必须提示1A0B.
当前已知N组猜谜者猜的数字与提示，如果答案确定，请输出答案，不确定则输出NA。

输入描述
第一行输入一个正整数，0 < N < 100.
接下来N行，每一行包含一个猜测的数字与提示结果。

输出描述
输出最后的答案，答案不确定则输出NA。

输入
6
4815 1A1B
5716 0A1B
7842 0A1B
4901 0A0B
8585 3A0B
8555 2A1B

输出
3585
 */
class Solution02
{
public:
    bool checkStr(string& target_str, string&check_str, int pos_correct, int num_correct)
    {
        unordered_set<int>pos_set; //记录位置正确，数字正确的index
        unordered_set<char>num_set;
        int size = target_str.size();
        for (int i=0; i< size; i++)
        {
	        if (target_str[i]==check_str[i])
	        {
                pos_set.insert(i);
	        }
            //位置正确的数字不能加进去
        	//后面扫到跟位置正确一样的数字，也不可以进
            num_set.insert(target_str[i]);
        }

        for (auto& pos_i:pos_set)
        {
            char curr_ch = target_str[pos_i];
	        if (num_set.count(curr_ch)>0)
	        {
                num_set.erase(curr_ch);
	        }
        }

        if (pos_set.size() != pos_correct) return false;

        int num_count = 0;
        for (int i=0; i<size; i++)
        {
            if (pos_set.count(i) > 0) continue;
            char check_ch = check_str[i];
            if (num_set.count(check_ch)>0)
            {
                num_count++;
            }
        }

        return num_count == num_correct;
        //checkStr
    }

    bool checkVerify(string& target_str, vector<vector<string>>& role_vec)
    {
        //1A1B 数字正确位置正确 数字正确而位置不对
        for (auto& item : role_vec)
        {
            string check_str = item[0];
            int pos_correct = item[1][0] - '0';
            int num_correct = item[1][2] - '0';
            if (!checkStr(target_str, check_str,pos_correct,num_correct))
            {
                return false;
            }
        }
        return true;
	    //checkVerify
    }

    Solution02(vector<vector<string>>&role_vec)
    {
        vector<string>result;

        //string num_str = "2012"; //2206
        //bool res = checkVerify(num_str, role_vec);
        //cout << res;
        for (int i=0; i<=9999; i++)
        {
            string num_str = to_string(i);
            while (num_str.size()<4)
            {
                num_str = '0' + num_str;
            }
            if (checkVerify(num_str, role_vec))
            {
                result.push_back(num_str);
            }
        }

        if (result.size()==1)
        {
            cout << result[0];
        }
        else
        {
            cout << "NA";
        }

	    //Solution02
    }
};


int main()
{
	{
/*
6
4815 1A1B
5716 0A1B
7842 0A1B
4901 0A0B
8585 3A0B
8555 2A1B
*/
        int v_size;
        cin >> v_size;
        vector<vector<string>>role_vec(v_size);
        for (int i=0; i<v_size; i++)
        {
            vector<string>role_item(2);
            cin >> role_item[0] >> role_item[1];
            role_vec[i] = role_item;
            //for---
        }

        Solution02 solu(role_vec);
        return 0;
	}
    string input;
    getline(cin, input);
    Solution01 solu(input);

}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
